home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************\
- *
- * Apple Macintosh Developer Technical Support
- *
- * Main program file
- *
- * Program: DavesFabSamples
- * File: DavesFabSamples.c
- *
- * by: Forrest Tanaka
- *
- * Copyright © 1988-1994 Apple Computer, Inc.
- * All rights reserved.
- *
- \******************************************************************************/
-
-
- /******************************************************************************\
- * Header Files
- \******************************************************************************/
-
- #include <Desk.h>
- #include <DiskInit.h>
- #include <Errors.h>
- #include <Fonts.h>
- #include <Menus.h>
- #include <Resources.h>
- #include <ToolUtils.h>
- #include <SegLoad.h>
-
- #include <AppleEvents.h>
- #include <GestaltEqu.h>
- #include <Packages.h>
- #include <Traps.h>
-
- #include <GXGraphics.h>
-
- #include "DavesFabSamples.h"
- #include "MenuHandler.h"
-
-
- /******************************************************************************\
- * Constants
- \******************************************************************************/
-
- #define kMaxSleepTime 60 /* # ticks willing to wait between minor switches */
-
-
- /******************************************************************************\
- * Macros
- \******************************************************************************/
-
- /* Return status of bth bit of m */
- #define btst(m,b) ((m) & (1L << (b)))
-
-
- /******************************************************************************\
- * Global Variables
- \******************************************************************************/
-
- Boolean gQuitting; /* True if user requested that this app quit */
- Boolean gWereInFront; /* True if this application is frontmost */
- Boolean gFixMenus; /* True if menus need fixing */
- Boolean gHasAppleEvents; /* True if Apple Events implemented */
- Boolean gHasCoolSF; /* True if 7.0 Standard File routines available */
-
- AEEventHandlerUPP gOurAEQuitHandler; // proc ptr for our event handler
-
- #if defined(powerc) || defined(__powerc)
- QDGlobals qd;
- #endif
-
-
- /******************************************************************************\
- * Private Function Prototypes
- \******************************************************************************/
-
- int main(void);
-
- void StartUp(void);
-
- void gxShutDown(void);
-
- void EventLoop(void);
-
- void DoMouseDown(
- EventRecord *anEvent);
-
- void DoKeyDown(
- EventRecord *anEvent);
-
- pascal OSErr HandleAEquit(
- AppleEvent *quitAppleEvent,
- AppleEvent *reply,
- long handlerRefCon);
-
- OSErr DoneRequiredParams(
- AppleEvent *anAppleEvent);
-
- void DoWindowClose(
- EventRecord *anEvent,
- WindowPtr eventWindow);
-
- void Exception (
- long msgType,
- long msgCode);
-
-
-
- /******************************************************************************\
- * Public: main - Entry gxPoint to this application
- *
- * After the gxHeap is initialized by allocating several master pointer blocks and
- * expanding the application’s gxHeap to its maximum size, StartUp is called to
- * complete initialization. Then the main event loop is entered, and that’s
- * where we stay until the user chooses Quit.
- \******************************************************************************/
-
- int main()
- {
- MaxApplZone(); /* Prepare the gxHeap */
- MoreMasters(); MoreMasters();
- MoreMasters(); MoreMasters();
- MoreMasters(); MoreMasters();
- MoreMasters(); MoreMasters();
-
- StartUp(); /* gxInitialize the application */
- EventLoop(); /* Execute the main event loop */
- gxShutDown(); /* Shut down the application */
-
- return 0; /* Return the ANSI way */
- }
-
-
- /******************************************************************************\
- * StartUp - Do whatever has to be done to gxInitialize the application
- *
- * This routine is called after the gxHeap is initialized to gxInitialize the
- * application. This involves initializing the toolbox, emergency memory,
- * loading up the menus, validating the current environment, and initializing
- * global variables. If any errors occur while doing this, StartUp displays
- * an alert telling the user what the error was and then ExitToShell is called.
- * This is an unusual way to react to errors, and I only do it here because it’s
- * so early in execution that there really isn’t much else that can be done.
- *
- * See EmergMem.h in this application for details about emergency memory.
- \******************************************************************************/
-
- static void StartUp()
- {
- short result; /* Result of alert; ignored */
- long aeAttrs; /* AppleEvent attributes */
- long sfAttrs; /* Standard File attributes */
- OSErr error;
- long msgType;
- long msgCode;
-
- /* gxInitialize Sarano */
- GXEnterGraphics();
-
- /* gxInitialize the toolbox */
- InitGraf( &qd.thePort );
- InitFonts();
- InitWindows();
- InitMenus();
- TEInit();
- InitDialogs( nil );
-
- /* gxInitialize emergency memory */
-
- /* gxInitialize the menus */
- error = StartMenus();
-
- if (error == memFullErr) Exception( rMemErrMessages, kMemErrAppOpenMsg );
- else if (error == resNotFound) Exception( rResErrMessages, kResErrAppDamageMsg );
- else if (error == dsSysErr) Exception( rMiscErrMessages, kMiscErrUnknownMsg );
-
-
- /* Check for the fancier capabilities */
-
- error = Gestalt( gestaltAppleEventsAttr, /*<*/&aeAttrs );
- if (error != noErr)
- gHasAppleEvents = false;
- else
- gHasAppleEvents = btst( aeAttrs, gestaltAppleEventsPresent );
-
- error = Gestalt( gestaltStandardFileAttr, /*<*/&sfAttrs );
- if (error != noErr)
- gHasCoolSF = false;
- else
- gHasCoolSF = btst( sfAttrs, gestaltStandardFile58 );
-
- /* Install the AppleEvent handler */
- if (gHasAppleEvents)
- {
- gOurAEQuitHandler = NewAEEventHandlerProc(HandleAEquit);
-
- error = AEInstallEventHandler( kCoreEventClass,
- kAEQuitApplication,
- gOurAEQuitHandler, 0, false );
-
- if (error == memFullErr) Exception( rMemErrMessages, kMemErrAppOpenMsg );
- else if (error != noErr) Exception( rMiscErrMessages, kMiscErrUnknownMsg );
- }
- }
-
-
- /******************************************************************************\
- * gxShutDown - Do whatever has to be done to shut down the application
- *
- * This routine is called when the application is about to shut down. It calls
- * GXExitGraphics to shut down Sarano graphics.
- \******************************************************************************/
-
- static void gxShutDown()
- {
- DisposeRoutineDescriptor(gOurAEQuitHandler); // dispose our routine descriptor
- GXExitGraphics();
- }
-
-
- /******************************************************************************\
- * EventLoop - Main event loop for this application
- *
- * This is the main event loop of this application. During every iteration of
- * the event loop, the menus are kept up-to-date. Also, NoEmergMem is called to
- * detect whether the emergency memory was used. If it was, then RecoverEmergMem
- * is called in an attept to get it back. If it can’t, then some commands could
- * be disabled until the memory can be recovered.
- \******************************************************************************/
-
- static void EventLoop()
- {
- EventRecord anEvent; /* An incoming event */
- WindowPtr lastWindow; /* Pointer to front window during last iteration */
- WindowPtr currWindow; /* Pointer to the current front window */
-
- gWereInFront = true;
- gQuitting = false;
- gFixMenus = true;
- lastWindow = nil;
-
- InitCursor();
-
- /* We loop until gQuitting is true */
-
- while (!gQuitting)
- {
- /* Fix the menus to reflect current conditions */
- currWindow = FrontWindow();
- if (currWindow != lastWindow || gFixMenus)
- {
- FixMenus();
- lastWindow = currWindow;
- gFixMenus = false;
- }
-
- /* It’s time to get and examine an event */
-
- if ( WaitNextEvent( everyEvent, &anEvent, kMaxSleepTime, nil ) )
- {
- switch (anEvent.what)
- {
- case mouseDown:
- DoMouseDown( &anEvent );
- break;
-
- case keyDown:
- case autoKey:
- DoKeyDown( &anEvent );
- break;
-
- case updateEvt:
- DoUpdateEvt( &anEvent );
- break;
-
- case kHighLevelEvent:
- (void)AEProcessAppleEvent( &anEvent );
- break;
- }
- }
- }
- }
-
-
- /******************************************************************************\
- * DoMouseDown - Mouse-down event dispatcher
- *
- * When a mouseDown event is received in the main event loop, this routine is
- * called to determine which area on the screens the mouseDown was, and to
- * dispatch to the appropriate routine to handle mouseDown events in that area.
- * The mouseDown event is passed in the anEvent parameter.
- *
- * See MenuHandler.h for routines that handle mouse-down events in the menu bar.
- \******************************************************************************/
-
- static void DoMouseDown(
- EventRecord *anEvent) /* Contains mouse-down event */
- {
- short clickArea; /* Area of the screen that was clicked */
- WindowPtr eventWindow; /* Pointer the clicked window, if any */
-
- /* Find clicked area of screen or window */
- clickArea = FindWindow( anEvent->where, /*<*/&eventWindow );
-
- /* Jump to mouseDown-handling routine appropriate for screen area */
- switch (clickArea)
- {
- case inMenuBar:
- DoMenuChoice( MenuSelect( anEvent->where ) );
- break;
- case inGoAway:
- DoWindowClose( anEvent, eventWindow );
- break;
- default:
- break;
- }
- }
-
-
- /******************************************************************************\
- * DoKeyDown - Key-down event dispatcher
- *
- * When a keyDown or autoKey event is received in the main event loop, this
- * routine is called to determine whether key is a command-key equivalent for a
- * menu item or not. If the command key isn’t down, then the key stroke is
- * ignored. Otherwise, MenuKey is called to get the menu ID and item number
- * of the menu item that corresponds to the command key, if any. Then
- * DoMenuChoice is called to dispatch to the appropriate routine for the chosen
- * menu item. The keyDown or autoKey event is passed in anEvent.
- \******************************************************************************/
-
- static void DoKeyDown(
- EventRecord *anEvent) /* Contains the key-down event */
- {
- char theKey; /* ASCII code of key that was pressed */
-
- /* Get the ASCII code of the pressed key */
- theKey = anEvent->message & charCodeMask;
-
- /* If anEvent was keyDown and command key was down, it’s menu command */
- if (anEvent->what == keyDown && (anEvent->modifiers & cmdKey))
- DoMenuChoice( MenuKey( theKey ) );
- }
-
-
- /******************************************************************************\
- * Private: DoWindowClose - Handle a click in the close box of a window
- *
- * This routine should be called when the user clicks in the close box of the
- * window specified by eventWind. The mouse is tracked until the user releases
- * the mouse button. If the user released the mouse button while the mouse was
- * in the close box, then DisposeWindow is called to close the window. anEvent
- * contains the mouse-down event that was determined to be a mouse click in the
- * window.
- \******************************************************************************/
-
- static void DoWindowClose(
- EventRecord *anEvent, /* Mouse-down event in the close box */
- WindowPtr eventWindow) /* Pointer to the window that was clicked */
- {
- if (TrackGoAway( eventWindow, anEvent->where ))
- DisposeWindow( eventWindow );
- }
-
-
- /******************************************************************************\
- * Private: HandleAEquit - Handler for 'quit' AppleEvent
- *
- * This is the AppleEvent handler for the 'quit' AppleEvent as passed in the
- * quitAppleEvent parameter by the AppleEvent Manager. The DoQuit routine is
- * called which causes this application to quit at the start of the next
- * iteration of the main event loop.
- *
- * Though the quit AppleEvent doesn’t contain any parameters, the standard thing
- * to do in reaction to any AppleEvent is to check to see if there are any
- * required parameters in the AppleEvent that this routine doesn’t recognise.
- * DoneRequiredParms checks for this condition and returns an error if there are
- * in fact required parameters in the AppleEvent or if some other error occurs
- * during the check.
- \******************************************************************************/
-
- static pascal OSErr HandleAEquit(
- AppleEvent *quitAppleEvent, /* Contains the ‘quit’ AppleEvent */
- AppleEvent *reply, /* Returns reply; ignored */
- long handlerRefCon) /* Application-defined parameter; ignored */
- {
- #pragma unused(reply,handlerRefCon)
- OSErr error;
-
- /* quit AE has no parms, but check in case the client requires any */
- error = DoneRequiredParams( quitAppleEvent );
-
- if (error == noErr)
- /* No extra parameters; handle Quit command */
- DoQuit();
-
- return error;
- }
-
-
- /******************************************************************************\
- * DoneRequiredParams - Done processing required params; OK?
- *
- * DoneRequiredParams checks to see if the AppleEvent specified by the
- * anAppleEvent parameter has any required parameters that we haven’t yet
- * processed. If there aren’t any left, then noErr is returned. If there are
- * required parameters that haven’t been processed yet, then errAEEventNotHandled
- * is returned. If any other errors occur, then that error code is returned.
- \******************************************************************************/
-
- static OSErr DoneRequiredParams(
- AppleEvent *anAppleEvent) /* AppleEvent being checked */
- {
- DescType typeCode; /* Type of AppleEvent attribute found; ignored */
- Size actualSize; /* Actual size of parameters; ignored */
- OSErr error;
-
- /* Are there any required parameters in AppleEvent we didn’t process? */
-
- error = AEGetAttributePtr(
- anAppleEvent,
- keyMissedKeywordAttr,
- typeWildCard,
- &typeCode,
- nil,
- 0,
- &actualSize );
-
- if (error == errAEDescNotFound)
- /* No required parameters left, so no error */
- error = noErr;
- else if (error == noErr)
- /* There was at least one required parameter we didn’t process */
- error = errAEEventNotHandled;
-
- return error;
- }
-
-
- /******************************************************************************\
- * Public: DoQuit
- *
- * Each open window is checked to see what kind it is, and then it is closed
- * appropriately.
- \******************************************************************************/
-
- void DoQuit()
- {
- WindowPtr aWindow; /* Pointer to each window in the window list */
-
- aWindow = FrontWindow();
-
- /* Keep closing a window until there are no windows left */
- while (aWindow != nil)
- {
- DisposeWindow( aWindow );
- aWindow = FrontWindow();
- }
-
- /* Tell the main event loop that we’re done */
- gQuitting = true;
- }
-
-
- /******************************************************************************\
- * Public: DoUpdateEvt
- *
- * As new kinds of windows are added to this application, this routine will have
- * to be able to detect the new kind of window and dispatch to the routine that
- * handles update events in that kind of window.
- \******************************************************************************/
-
- void DoUpdateEvt(
- EventRecord *anEvent) /* Update event */
- {
- WindowPtr eventWindow; /* Pointer to the window to update */
-
- /* Get a pointer to the window that needs an update */
- eventWindow = (WindowPtr)anEvent->message;
-
- /* Update the window that needs it */
- SetPort( eventWindow );
- BeginUpdate( eventWindow );
- EndUpdate( eventWindow );
- }
-
-
- /******************************************************************************\
- * Public: ShowAlert
- *
- * To position the alert before it’s displayed, the ALRT resource is loaded
- * before it’s displayed, and its boundsRect is put into the proper position
- * through the CenterScreenRect routine. Because this modifies the ALRT
- * resource in memory and because ALRT resources are normally purgeable, it must
- * be made unpurgeable until the alert is dismissed.
- \******************************************************************************/
-
- short ShowAlert(
- short alertType, /* Type of alert to display */
- short buttonOption, /* Button options for alert */
- short messageClass, /* Class of message to display in alert */
- short messageIndex) /* Index of message to display in alert */
- {
- short itemHit; /* Item number of clicked item */
- Str255 aMessage;
-
- /* Put the specified message into the dialog parameter text */
- if (messageIndex != 0)
- {
- GetIndString( aMessage, messageClass, messageIndex );
- ParamText( aMessage, "\P", "\P", "\P" );
- }
-
- /* Show the stop alert */
- InitCursor();
-
- /* Present the alert */
- if (alertType == kGenericAlert) itemHit = Alert( buttonOption, nil );
- else if (alertType == kNoteAlert) itemHit = NoteAlert( buttonOption, nil );
- else if (alertType == kCautionAlert) itemHit = CautionAlert( buttonOption, nil );
- else if (alertType == kStopAlert) itemHit = StopAlert( buttonOption, nil );
-
- return itemHit;
- }
-
-
- /******************************************************************************\
- * Exception - Signal that an exception has occured and exit
- \******************************************************************************/
-
- void Exception ( long msgType, long msgCode)
- {
- ShowAlert( kStopAlert, rOKAlertID, msgType, msgCode );
- ExitToShell();
- }
-